﻿#include <mutex>
#include <unordered_map>
#include <string>
#include "GlobalSymbol.h"

static std::mutex g_mutex;

struct SymbolInfo {
	void* data;
	SymbolDestructor des;
	int use_cnt;
};

std::unordered_map<std::string, SymbolInfo> d;

void * GetOrCreateSymbol(const char * SymbolName, int size, SymbolConstructor cons, SymbolDestructor des)
{
	std::lock_guard<std::mutex> lock(g_mutex);

	void* ret = NULL;

	if (d.count(SymbolName)) {
		auto & info = d[SymbolName];
		ret = info.data;
		info.use_cnt++;
	}
	else {
		SymbolInfo info{};
		info.data = malloc(size);
		if (cons) {
			cons(info.data);
		}
		
		info.des = des;
		info.use_cnt = 1;
		ret = info.data;
		d[SymbolName] = info;
	}

	return ret;
}

void ReleaseSymbol(const char * SymbolName)
{
	std::lock_guard<std::mutex> lock(g_mutex);
	
	if (d.count(SymbolName)) {
		auto & info = d[SymbolName];
		info.use_cnt--;

		if (info.use_cnt == 0) {
			if (info.des) {
				info.des(info.data);
				free(info.data);
			}
			d.erase(SymbolName);
		}
	}
}
